Skip to content

fix #4251: wrap BackgroundTasks in their own span#4368

Open
davidgss04 wants to merge 1 commit intoopen-telemetry:mainfrom
davidgss04:fix-bug-4251
Open

fix #4251: wrap BackgroundTasks in their own span#4368
davidgss04 wants to merge 1 commit intoopen-telemetry:mainfrom
davidgss04:fix-bug-4251

Conversation

@davidgss04
Copy link
Copy Markdown

Description

Fixes #4251

FastAPI background tasks were not properly instrumented. While request spans were created correctly, background tasks executed after the response without their own span. As a result, any spans created inside a background task were incorrectly attached directly to the request span, which had already finished, leading to broken trace hierarchies and inaccurate timing information.

The fix patches BackgroundTask.__call__ to wrap its execution in a dedicated span. This ensures that each background task runs within its own span, correctly parented to the request span, and that any spans created inside the task are properly nested.

The patch is applied only once using a guard (hasattr) to avoid double instrumentation, and the original method is restored during uninstrument_app to prevent side effects.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Testing

Added three regression tests:

  • test_background_task_span_parents_inner_spans — verifies that background tasks create a wrapper span and that spans created inside the task are correctly parented

  • test_uninstrument_app_restores_background_task_call — ensures the original BackgroundTask.__call__ is restored after uninstrumentation

  • test_background_task_span_not_duplicated_on_double_instrument_app — verifies that repeated instrumentation does not create duplicate spans or apply the patch multiple times

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla bot commented Mar 27, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: davidgss04 / name: David Santos (ab9b962)

@tammy-baylis-swi
Copy link
Copy Markdown
Contributor

Thanks for this! The fix to Background tracing makes sense to me and there is no semconv requirement to add HTTP attributes to that particular span. Metrics generated will be the same.

Please could you also commit fixes from:

  • tox -e precommit
  • tox -e lint-instrumentation-fastapi

@tammy-baylis-swi tammy-baylis-swi moved this to Reviewed PRs that need fixes in Python PR digest Mar 27, 2026
Only the request/ASGI middleware was traced; background tasks
were not.

Background tasks ran after the response with no span, causing
child spans to attach to a closed parent span.

This change patches BackgroundTask.__call__ to wrap execution
in a new span.

Each background task now creates a child span of the request,
ensuring a correct trace hierarchy.

Add three regression tests for background task instrumentation.
@davidgss04
Copy link
Copy Markdown
Author

Thanks for this! The fix to Background tracing makes sense to me and there is no semconv requirement to add HTTP attributes to that particular span. Metrics generated will be the same.

Please could you also commit fixes from:

* `tox -e precommit`

* `tox -e lint-instrumentation-fastapi`

Good evening, I have applied the requested precommit and lint-instrumentation-fastapi fixes and updated the PR. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Reviewed PRs that need fixes

Development

Successfully merging this pull request may close these issues.

[fastapi] BackgroundTasks produce child spans that outlive their closed parent span

2 participants